package com.example.okhttp3.testproject;



import com.example.okhttp3.utils.ILogUtil;

import okhttp3.Request;
import okhttp3.Response;
import okhttp3.Call;
import okhttp3.OkHttpClient;

import java.io.IOException;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLSocketFactory;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.lang.InterruptedException;

//import org.greenrobot.eventbus.EventBus;



class ThreadTest extends Thread {
	
	
    private Call call;
    private int delayCancel;
    public ThreadTest(Call call, int delayCancel) {
        this.call = call;
        this.delayCancel = delayCancel;
    }

    public void run () {
        try {
            Thread.sleep(delayCancel);
        } catch (InterruptedException e) {
            System.out.println("Thread interrupted.");
        }
        call.cancel();
    }
}

public class OkHttp3Instance {
	public static final String TAG = "HJS";
	
    public class addressPair {
        String ipAddress;
        int port;
    }
    public static String ipAddressSslFailure = "39.108.71.209";
    public static String ipAddressUnreachable = "7.6.5.4";
    public static String ipAddressSecondUnreachable = "4.5.6.7";
    public static String ipAddressNoPortListening = "10.67.129.174";
    public static String ipAddressOk = "10.3.42.43"; // ok for w3
    public OkHttpClient client;
    public OkHttp3Instance(int interval) {
        client = new OkHttpClient().newBuilder()
                .sslSocketFactory(createSSLSocketFactory())
                .hostnameVerifier(new TrustAllHostnameVerifier())
                .connectionAttemptDelay(interval, TimeUnit.MILLISECONDS)
                .build();
        
    }

    public static SSLSocketFactory createSSLSocketFactory() {
        SSLSocketFactory sSLSocketFactory = null;
        try {
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, new TrustManager[]{new TrustAllManager()},
                    new SecureRandom());
            sSLSocketFactory = sc.getSocketFactory();
        } catch (Exception e) {
        }
        return sSLSocketFactory;
    }

    public static class TrustAllManager implements X509TrustManager {
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
        }
        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType)
                throws CertificateException  {
        }
        @Override
        public X509Certificate[] getAcceptedIssuers() {
            //return null;
            return new X509Certificate[] {};
        }
    }
    public static class TrustAllHostnameVerifier implements HostnameVerifier {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    }

    // code request code here
    public static void invalidIpTest(String url) throws IOException {
        String invalidIp = "192.168.0.256";
        String unknownHost = "www.unknownHost.abc";
        ArrayList<String> addresses = new ArrayList<String>();
        addresses.add(ipAddressUnreachable);
        addresses.add("www.baidu.com");
        addresses.add(invalidIp);
        //addresses.add(unknownHost);

        try {
//            Request request = new Request.Builder()
//                    .url(url)
//                    .additionalIpAddresses(addresses)
//                    .addIpAddress(invalidIp)
//                    .build();
        } catch (Exception e) {
        	
			ILogUtil.exception(TAG, e);
        }
    }
    public void doGetRequest(String url, boolean concurrentConnect, int cancelDelay,
                             ArrayList<String> additionalAddresses) throws IOException {
        
    	ILogUtil.d(TAG, "get");
    	
    	Request request = new Request.Builder()
                .url(url)
                .concurrentConnectEnabled(concurrentConnect)
                .additionalIpAddresses(additionalAddresses)
                .build();
    	ILogUtil.d(TAG, "get 2");
        Call call = client.newCall(request);

        // Enabled to test multithread.
//        if (cancelDelay > 0) {
//            ThreadTest tt = new ThreadTest(call, cancelDelay);
//            tt.start();
//        }
        ILogUtil.d(TAG, "get 3");
        //System.out.println("Before execute: " + url + ":" + port + ", "
        //	  + "Concurrent Connect Enabled: " + concurrentConnect + ", delay to cancel: " + cancelDelay);
        
        Response response = call.execute();
        ILogUtil.d(TAG, "get 4");
        ILogUtil.d(TAG, response.body().string());
        ILogUtil.d(TAG,  "response code = " + response.code());
        
//        EventBus.getDefault().post(new MessageEvent(MessageEvent.TEST_MESSAGE,  "response code = " + response.code()));
        response.body().close();
    }
//
//    public static void concurrentConnect(String url) throws IOException {
//        Demo demo = new Demo(500);
//        ArrayList<String> addresses = new ArrayList<String>();
////        addresses.add(ipAddressUnreachable);        // Host unreachable.
////        addresses.add(ipAddressUnreachable);        // Duplicate Host.
////        addresses.add(ipAddressSecondUnreachable);        // Host unreachable.
////        addresses.add(ipAddressSecondUnreachable);        // Host unreachable.
//    //    addresses.add("14.215.177.39");
//        addresses.add("183.61.241.225");
//
//        //addresses.add(ipAddressOk);
//        try {
//            demo.doGetRequest(url, true, 0, addresses);
//        } catch (IOException e) {
//        	ILogUtil.exception(TAG, e);
//        }
//    }
//
//    public static void concurrentConnectWithSSLFailure(String url) throws IOException {
//        Demo demo = new Demo(200);
//        ArrayList<String> addresses = new ArrayList<String>();
//        addresses.add(ipAddressSslFailure);   // Port 443 listen for HTTP
//        addresses.add(ipAddressUnreachable);  // Host unreachable.
//        addresses.add(ipAddressSecondUnreachable);        // Host unreachable.
//        //addresses.add(ipAddressOk);
//        try {
//            demo.doGetRequest(url, true, 0, addresses);
//        } catch (IOException e) {
//            ILogUtil.exception(TAG, e);
//        }
//    }
//
//    public static void concurrentConnectWithPortResetSSLFailure(String url) throws IOException {
//        Demo demo = new Demo(1100);  // Delay set to 1.1 second to proper detect reset address
//        ArrayList<String> addresses = new ArrayList<String>();
//        addresses.add(ipAddressUnreachable);  // Host unreachable.
//        addresses.add(ipAddressNoPortListening);  // Port not listening
//        addresses.add(ipAddressSslFailure);   // Port 443 listen for HTTP
//        addresses.add(ipAddressUnreachable);  // Host unreachable.
//        addresses.add(ipAddressSecondUnreachable);        // Host unreachable.
//        //addresses.add(ipAddressOk);
//        try {
//            demo.doGetRequest(url, true, 0, addresses);
//        } catch (IOException e) {
//        	ILogUtil.exception(TAG, e);
//        }
//    }
//
//    public static void concurrentConnectWithCancellation(String url) throws IOException {
//        Demo demo = new Demo(200);
//        ArrayList<String> addresses = new ArrayList<String>();
//        addresses.add(ipAddressUnreachable);        // Host unreachable.
//        addresses.add(ipAddressUnreachable);        // Duplicate Host.
//        addresses.add(ipAddressSecondUnreachable);        // Host unreachable.
//        //addresses.add(ipAddressOk);
//        try {
//            demo.doGetRequest(url, true, 300, addresses);
//        } catch (IOException e) {
//        	ILogUtil.exception(TAG, e);
//        }
//    }
//
//    public static void normalRequest(String url) throws IOException {
//        Demo demo = new Demo(200);
//        ArrayList<String> addresses = new ArrayList<String>();
//        try {
//            demo.doGetRequest(url, false, 0, addresses);
//        } catch (IOException e) {
//        	ILogUtil.exception(TAG, e);
//        }
//    }

    
}
